﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;

namespace Benchmarks
{

    public class BoxingSuite : BenchmarkSuite{
        public BoxingSuite() :
            base( "Object[] vs StrongTypedGetter",
            new IntArrayData(10),
            new ObjectArrayData(10),
            new ObjectWrappedArrayData(10),
            new StrongTypedData()
            ) { }
    }

    public class IntArrayData : Benchmark
    {
        private string m_Category;
        private String m_Name;
        public override string Category { get { return m_Category; } }
        public override string Name { get { return m_Name; } }

        public static String current_string;
        public static int current_int;

        private readonly int[] m_Data;

        public IntArrayData(int size)
        {
            m_Category = "Object[] vs StrongTypedGetter";
            m_Name = "IntArray " + size;

            m_Data = new int[size];
            for (int i = 1; i < size; i++)
            {
                m_Data[i] = i;
            }
        }

        public override void StartTrials()
        {
        }


        public override void RunOverheadTest(int num_iterations)
        {
        }

        public override void RunTrial(int num_iterations)
        {
            for (int i = 1; i < num_iterations; i++)
            {
                current_int += m_Data[0];//i%m_Data.Length ];
            }
        }
    }

    public class ObjectArrayData : Benchmark {
        private string m_Category;
        private String m_Name;
        public override string Category { get { return m_Category; } }
        public override string Name { get { return m_Name; } }

        public static String current_string;
        public static int current_int;

        private readonly Object[] m_Data;

        public ObjectArrayData( int size ) {
            m_Category = "Object[] vs StrongTypedGetter";
            m_Name = "ObjectArray " + size;

            m_Data = new Object[size];
            for( int i=0 ; i < size ; i++ ) {
                m_Data[ i ] = i;
            }
        }

        public override void StartTrials() {
        }

        public override void RunOverheadTest(int num_iterations){}

        public override void RunTrial(int num_iterations)
        {
            for (int i = 0; i < num_iterations; i++) {
                current_int += (int)m_Data[0];//i%m_Data.Length ];
            }
        }
    }
    public class ObjectWrappedArrayData : Benchmark
    {
        private string m_Category;
        private String m_Name;
        public override string Category { get { return m_Category; } }
        public override string Name { get { return m_Name; } }

        public static String current_string;
        public static int current_int;

        private readonly Object[] m_Data;
        public class ObjectWrapper {
            private Object[] m_Data;
            public ObjectWrapper(Object[] data) { m_Data = data; }
            public Object this[int index] { get { return m_Data[ index ]; } }
        }

        private readonly ObjectWrapper m_Wrapper;

        public ObjectWrappedArrayData(int size)
        {
            m_Category = "Object[] vs StrongTypedGetter";
            m_Name = "ObjectWrappedArray " + size;

            m_Data = new Object[size];
            for (int i = 0; i < size; i++)
            {
                m_Data[i] = i;
            }
            m_Wrapper = new ObjectWrapper( m_Data );
        }

        public override void StartTrials()
        {
        }

        public override void RunOverheadTest(int num_iterations) { }

        public override void RunTrial(int num_iterations)
        {
            for (int i = 0; i < num_iterations; i++) {
                current_int += (int)m_Wrapper[ 0 ];
            }
        }
    }

    public class StrongTypedData : Benchmark
    {
        private string m_Category;
        private String m_Name;
        public override string Category { get { return m_Category; } }
        public override string Name { get { return m_Name; } }

        private readonly Dictionary<String, int> m_Lookup;
        private readonly TestClass m_TestClass;

        private class TestClass {
            private readonly int a0;
            public TestClass() { a0 = 1; }
            public int A0 { get { return a0; } } //set { a0 = value; } }
        }

        public StrongTypedData()
        {
            m_Category = "Object[] vs StrongTypedGetter";
            m_Name = "StrongTypedGetter";
            m_TestClass = new TestClass();
            //m_TestClass.A0 = 0;
            //m_TestClass.A1 = 1;
            //m_TestClass.A2 = 2;
            //m_TestClass.A3 = 3;
            //m_TestClass.A4 = 4;
            //m_TestClass.A5 = 5;
            //m_TestClass.A6 = 6;
            //m_TestClass.A7 = 7;
            //m_TestClass.A8 = 8;
            //m_TestClass.A9 = 9;
        }

        public override void StartTrials(){}
        public static String current_string;
        public static int current_int;

        public override void RunOverheadTest(int num_iterations)
        {
        }

        public override void RunTrial(int num_iterations)
        {
            for (int i = 0; i < num_iterations ; i++) {
                current_int += m_TestClass.A0;
                //current_int = m_TestClass.A1;
                //current_int = m_TestClass.A2;
                //current_int = m_TestClass.A3;
                //current_int = m_TestClass.A4;
                //current_int = m_TestClass.A5;
                //current_int = m_TestClass.A6;
                //current_int = m_TestClass.A7;
                //current_int = m_TestClass.A8;
                //current_int = m_TestClass.A9;
            }
        }
    }

}
